package com.ant.storage.dataSource;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.Objects;

/**
 * @author hzd
 * @version 1.0
 * @date 2023/12/26 11:36
 */
/**
 * @Description: 动态数据源通知
 */
@Aspect
//保证该AOP在@Transactional之前执行
@Order(1)
@Component
@Slf4j
public class DynamicDataSourceAspect {

    @Pointcut("@annotation(com.ant.storage.dataSource.DataSource)"
            + "|| @within(com.ant.storage.dataSource.DataSource)")
    public void dsPointCut(){}
    @Around("dsPointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
        DataSource dataSource = getDataSource(joinPoint);
        if (dataSource != null){
            DynamicDataSourceContextHolder.setDataSourceType(dataSource.value().name());
        }
        try {
            return joinPoint.proceed();
        }
        finally {
            // 销毁数据源 在执行方法之后
            DynamicDataSourceContextHolder.getDataSourceType();
        }
    }


    /**
     * 获取需要切换的数据源
     */
    public DataSource getDataSource(ProceedingJoinPoint point) {
        MethodSignature signature = (MethodSignature) point.getSignature();
        DataSource dataSource = AnnotationUtils.findAnnotation(signature.getMethod(), DataSource.class);
        if (Objects.nonNull(dataSource)) {
            return dataSource;
        }
        return AnnotationUtils.findAnnotation(signature.getDeclaringType(), DataSource.class);
    }
//
//
//    //定义切入点，即切入到自定义的注解类的路径
//    @Pointcut("@annotation(com.ant.storage.dataSource.TargetDataSource)")
//    public void dynamicDataSourceAspect() {
//    }
//
//    //切入点之前进行的操作
//    @Before("dynamicDataSourceAspect() && @annotation(ds)")
//    public void beforeDatasource(JoinPoint joinPoint, TargetDataSource ds) {
//        //获取注解中的值
//        String value = ds.value();
//        //判断当前注解里的值是否存在
//        if (DynamicDataSourceContextHolder.containsDataSource(value)) {
//            //如果存在，则使用注解中的数据
//            DynamicDataSourceContextHolder.setDataSourceType(value);
//        } else {
//            //不存在则使用默认数据源
//            DynamicDataSourceContextHolder.setDataSourceType("first");
//        }
//    }
//
//    //执行完方法之后，将threadLocal变量的数据源清空
//    @After("@annotation(ds)")
//    public void remoteDatasource(JoinPoint point, TargetDataSource ds) {
//        DynamicDataSourceContextHolder.clearDataSourceType();
//    }

}
